package com.wkkun.particle.base

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.PixelFormat
import android.graphics.PorterDuff
import android.os.Handler
import android.os.HandlerThread
import android.util.AttributeSet
import android.view.SurfaceHolder
import android.view.SurfaceView
import com.wkkun.particle.util.Constant
import java.util.*
import kotlin.collections.ArrayList

/**
 *Date:2020/5/8
 *Author:wang kunkun
 *Des:
 **/
class ParticleSurfaceView(context: Context, attributeSet: AttributeSet) :
    SurfaceView(context, attributeSet), BaseParticle, SurfaceHolder.Callback, Runnable {

    private var particleAdapter: ParticleAdapter? = null
    private var isAutoPlay = true
    private var intervalTime = 10 * Constant.RENDER_TIME
    private var renderTime = Constant.RENDER_TIME
    private var increaseParticleCount = 1
    private var childTotal = Int.MAX_VALUE
    private var temTime = -1

    private val surfaceHolder: SurfaceHolder = holder
    private lateinit var handlerThread: HandlerThread
    private lateinit var renderHandler: Handler

    //缓存的view
    private var cacheItems = LinkedList<BaseItem>()
    //要绘制的所有View
    private var drawItems = ArrayList<BaseItem>()

    init {
        surfaceHolder.setKeepScreenOn(true)
        surfaceHolder.addCallback(this)
        isFocusable = true
        isFocusableInTouchMode = true
        setZOrderOnTop(true)
        //设置背景为透明色
        surfaceHolder.setFormat(PixelFormat.TRANSPARENT)
    }

    override fun preCreate() {
        repeat(particleAdapter?.preCreateCount() ?: 0) {
            val newItem = particleAdapter!!.newItem(measuredWidth, measuredHeight)
            newItem.preInit(context)
            drawItems.add(newItem)
        }
    }

    override fun getItem(): BaseItem {
        val newItem = if (cacheItems.size > 0) {
            cacheItems.removeFirst()
        } else {
            particleAdapter!!.newItem(measuredWidth, measuredHeight)
        }
        newItem.init(context)
        return newItem
    }

    override fun drawItems(canvas: Canvas) {
        if (drawItems.size < childTotal) {
            if (temTime == -1) {
                temTime = ((intervalTime / renderTime.toFloat() + 0.5).toInt())
            } else if (temTime == 0) {
                repeat(increaseParticleCount) {
                    drawItems.add(getItem())
                }
            }
            temTime--
        }
        drawItems.forEach {
            it.draw(canvas)
        }
    }

    override fun transForms() {
        val iterator = drawItems.iterator()
        while (iterator.hasNext()) {
            val next = iterator.next()
            val isLive = next.move()
            if (!isLive) {
                iterator.remove()
                cacheItems.add(next)
            }
        }
    }

    override fun destroyAllView() {
        drawItems.forEach {
            it.destroy()
        }
        cacheItems.forEach {
            it.destroy()
        }
    }

    override fun startAnimation() {
        renderHandler.removeCallbacks(this)
        renderHandler.post(this)
    }

    override fun stopAnimation() {
        renderHandler.removeCallbacks(this)
    }

    override fun setAdapter(adapter: ParticleAdapter) {
        particleAdapter = adapter
        if (particleAdapter!!.maxParticleCount() <= 0) {
            return
        }
        childTotal = particleAdapter!!.maxParticleCount()
    }

    override fun setRenderTime(renderTime: Long) {
        if (intervalTime < renderTime || renderTime < 0) {
            return
        }
        this.renderTime = renderTime
    }

    override fun setIncreaseParticleInterval(intervalTime: Long) {
        if (intervalTime < renderTime || renderTime < 0) {
            return
        }
        this.intervalTime = intervalTime
    }

    override fun setIncreaseParticleCount(count: Int) {
        if (count <= 0) {
            return
        }
        increaseParticleCount = count
    }

    override fun setIsAutoPlay(isAuto: Boolean) {
        isAutoPlay = isAuto
    }

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
        renderHandler.removeCallbacks(this)
        destroyAllView()
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {
        if (particleAdapter == null) {
            throw NullPointerException("particleAdapter must not be null")
        }
        handlerThread = HandlerThread("BaseSurfaceView")
        handlerThread.start()
        renderHandler = Handler(handlerThread.looper)
        preCreate()
        if (isAutoPlay) {
            renderHandler.post(this)
        }
    }

    override fun run() {
        transForms()
        val lockCanvas = surfaceHolder.lockCanvas(null)
        lockCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
        drawItems(lockCanvas)
        surfaceHolder.unlockCanvasAndPost(lockCanvas)
        renderHandler.postDelayed(this, renderTime)
    }
}